#include "Config.h"
#include "Gpio.h"
#include "System.h"

typedef union{
  uint8_t value;
  struct {
    uint8_t Tim10msFlag:1;
    uint8_t Tim20msFlag:1;
    uint8_t Tim100msFlag:1;
    uint8_t KeyPower:1;
    uint8_t KeyUp:1;
    uint8_t KeyDown:1;
  } bits;
} flag_t;

xdata uint8_t Tim10msCnt = 0;
xdata uint8_t Tim20msCnt = 0;
xdata uint8_t Tim100msCnt = 0;
xdata uint8_t BL_PWM_Period = 0;
xdata uint8_t BL_PWM_Percent = 0;

flag_t SystemFlag;

inline void BL_PWM_Set(uint8_t percent){
  BL_PWM_Percent = percent;
  if(percent == 0){
    PIN_BL_PWM = 0;
  } else if(percent >= 100){
    PIN_BL_PWM = 1;
    BL_PWM_Percent = 0;
  }
}

#ifdef USE_SDCC
void timer0_irq_handler(void) interrupt(INT_NO_TMR0) using(1)
#else
void timer0_irq_handler(void) __AdapterDeclation(interrupt INT_NO_TMR0 using 1) //100us
#endif
{
  //100us
  if (++Tim10msCnt >= 125) {//0.25% 偏移
    SystemFlag.bits.Tim10msFlag = true;
    Tim10msCnt = 0;
    if (++Tim100msCnt >= 10) {
      SystemFlag.bits.Tim100msFlag = true;
      Tim100msCnt = 0;
    }
  }
  if (++Tim20msCnt >= 250) {
    SystemFlag.bits.Tim20msFlag = true;
    Tim20msCnt = 0;
  }
  if(BL_PWM_Percent){
    BL_PWM_Period++;
    if(BL_PWM_Period == 0){
      PIN_BL_PWM = 1;
    } else if(BL_PWM_Period == BL_PWM_Percent){
      PIN_BL_PWM = 0;
    } else if(BL_PWM_Period >= 100){
      BL_PWM_Period = 255;
    }
  }
}

#ifdef USE_SDCC
void intr0_irq_handler(void) interrupt(INT_NO_INT0) using(1)
#else
void intr0_irq_handler(void) __AdapterDeclation(interrupt INT_NO_INT0 using 1)
#endif
{
  // 中断处理
  // uint8_t dataCount = 0;
  // intr0_irq_enable(false);
  // if (touchpad_status == tpStop){
  //   intr0_irq_enable(true);
  // }
  // else{
  //   // dataCount = i2c_master_recv(i2c_read_buf, PACKET_SIZE);
  //   if (dataCount != PACKET_SIZE){
  //     //Uart0Printf("read buf fail\r\n");
  //     intr0_irq_enable(true);
  //   } else {
  //     touchpad_status = tpIrq;
  //   }
  // }
}

inline void TimerInit() {
  uint16_t tick;
  Timer0Init(tm8bitsAutoload, tnclkFsysDiv12);
  tick = TimerxTick(tnclkFsysDiv12, 100);
  Timer0Reload(256 - tick, 256 - tick);
  
  timer0_enable(true);
  timer0_irq_clear();
  timer0_irq_enable(true);
}

inline void GpioInit(){
  GpioCfgP1(gpioModePushPullUpInputOutput, PIN_HPD_EN_P17);
  GpioCfgP3(gpioModePushPullUpInputOutput, PIN_BL_PWM_P34);
  GpioCfgP3(gpioModePushPullUpInputOutput, PIN_KEY_POWE_P10);
  GpioCfgP3(gpioModePushPullUpInputOutput, PIN_KEY_UP_P11);
  GpioCfgP3(gpioModePushPullUpInputOutput, PIN_KEY_DOWN_P33);

  PIN_HPD_EN = 0;
  PIN_BL_PWM = 0;
}

inline void KeyScan(){
  static xdata uint8_t KeyPowerCnt = 0;
  static xdata uint8_t KeyUpCnt = 0;
  static xdata uint8_t KeyDownCnt = 0;
  static xdata uint8_t KeyPowerStatus = 0;
  static xdata uint8_t KeyUpStatus = 0;
  static xdata uint8_t KeyDownStatus = 0;

  SystemFlag.bits.KeyPower = PIN_KEY_POWER;
  SystemFlag.bits.KeyUp = PIN_KEY_UP;
  SystemFlag.bits.KeyDown = PIN_KEY_DOWN;
  if(PIN_KEY_POWER == 0){
    KeyPowerCnt++;
    if(KeyPowerCnt > 10){
      KeyPowerCnt = 10;
      KeyPowerStatus = 1;
    } else if(KeyPowerCnt > 200){
      KeyPowerCnt = 200;
      KeyPowerStatus = 2;
    }
  } else {
    if(KeyPowerCnt > 3){
      if(KeyPowerStatus){
        KeyPowerCnt = 3;
      } else {
        KeyPowerCnt = 0;
      }
    } else if(KeyPowerCnt){
      KeyPowerCnt--;
    } else {
      if(KeyPowerStatus){
        KeyPowerStatus = KeyPowerStatus << 4;
      }
    }
  }
  if(SystemFlag.bits.KeyUp){
    KeyUpCnt++;
  } else {
    KeyUpCnt = 0;
  }
  if(SystemFlag.bits.KeyDown){
    KeyDownCnt++;
  } else {
    KeyDownCnt = 0;
  }
}

void main(void) {
  static uint8_t Time1sCnt = 0;
  SystemInit(sf16MHz);
  GpioInit();
  TimerInit();
  Uart0Init(umM1_8BitsT1T2, ubcTimer1, 10000);

  WdtModeSelect(true);
  irq_enable(true);
  BL_PWM_Set(90);
  while (1) {
    if(SystemFlag.bits.Tim10msFlag) {
      SystemFlag.bits.Tim10msFlag = false;
      KeyScan();
    }
    if (SystemFlag.bits.Tim20msFlag) {
      SystemFlag.bits.Tim20msFlag = false;
      WdtFeed(50);
    }
    if (SystemFlag.bits.Tim100msFlag) {
      SystemFlag.bits.Tim100msFlag = false;
      if (++Time1sCnt >= 10) {
        Time1sCnt = 0;
        Uart0Printf("ABcdE\r\n");
      }
    }
  }
}
